package com.wang.tool.task;


import com.alibaba.fastjson.JSON;

import java.io.Serializable;
import java.util.Date;
import java.util.Random;

/**
 * @Description 任务状态
 * @Author shaopeng
 * @Date 2023/6/2
 * @Version 1.0
 */
public class TaskStage implements Serializable {

    private static final long serialVersionUID = 860550512608493076L;
    private static final Random RANDOM = new Random();


    /**
     * 任务id
     */
    private Long id;

    /**
     * 状态码 标记此次执行后数据的状态
     * 不可直接修改
     *
     * @see nextTime
     * @see complete
     * @see pause
     */
    private TaskStatus status;

    /**
     * 业务状态码
     * handler完全自定义
     */
    private String bizStatus;

    /**
     * 下次自检时间
     * 为空代表不自检
     */
    private Date checkTime;

    /**
     * 三方任务id
     * 如果有提交三方任务的
     */
    private String outId;

    /**
     * 任务模型
     * 自定义
     * db中json化存储
     */
    private Object model;


    /**
     * 下次再验证
     * 指定下次检验时间是在此之后的多少s
     * 防止聚集触发 所以采用一定的随机比例
     *
     * @param second   非空
     * @param minRatio 最小阈值比例 0-1 不要大于1
     */
    public TaskStage nextTime(int second, double minRatio) {
        if (minRatio > 1 || minRatio < 0) {
            throw new IllegalArgumentException("minRatio must in 0-1");
        }
        double randomRatio = minRatio + (1 - minRatio) * RANDOM.nextDouble();
        this.checkTime = new Date(System.currentTimeMillis() + Math.round(second * randomRatio) * 1000L);
        this.status = TaskStatus.WAIT;
        return this;
    }

    /**
     * 下次在验证
     * @param checkTime 非空 下次验证的时间
     * @return
     */
    public TaskStage nextTime(Date checkTime) {
        if (checkTime == null) {
            throw new IllegalArgumentException("checkTime can not be null");
        }
        this.checkTime = checkTime;
        this.status = TaskStatus.WAIT;
        return this;
    }


    /**
     * 任务结束
     *
     * @param success 是否成功
     * @return
     */
    public TaskStage complete(boolean success) {
        this.status = success ? TaskStatus.SUCCESS : TaskStatus.FAIL;
        return this;
    }

    /**
     * 暂停
     *
     * @return
     */
    public TaskStage pause() {
        this.status = TaskStatus.PAUSE;
        return this;
    }


    /**
     * 业务状态码
     *
     * @param status
     * @return
     */
    public TaskStage bizStatus(String status) {
        this.bizStatus = status;
        return this;
    }

    public TaskStage model(Object model) {
        this.model = model;
        return this;
    }

    public TaskStage outId(String outId) {
        this.outId = outId;
        return this;
    }


    public Date getCheckTime() {
        return checkTime;
    }

    public void setCheckTime(Date checkTime) {
        this.checkTime = checkTime;
    }

    public Object getModel() {
        return model;
    }

    public void setModel(Object model) {
        this.model = model;
    }

    public String getOutId() {
        return outId;
    }

    public void setOutId(String outId) {
        this.outId = outId;
    }

    public TaskStatus getStatus() {
        return status;
    }


    public String getBizStatus() {
        return bizStatus;
    }

    public void setBizStatus(String bizStatus) {
        this.bizStatus = bizStatus;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

}
